home *** CD-ROM | disk | FTP | other *** search
- {
- ========================================================
-
- EARTH INVADERS (Original LCD game by CGL 1982..)
- (I feel a copyright wangle coming on - NOT!)
-
- --------------------------------------------------------
-
- PC CONVERSION EXCLUSIVELY FOR SWAG, BY SCOTT TUNSTALL 1996
- (But why? ;) )
-
- Reqs: Turbo Pascal 5.5 +
- CGA
- Good technique in chatting up women
-
-
- ==========
-
- DISCLAIMER
-
- ----------
-
- I (Scott Tunstall) am not responsible if this program causes any
- damage to ANY hardware or software part of the computer system it
- runs on or detriment to mental health caused (finding any bugs I
- may have missed) OK?.
-
- You can alter/delete or even ADD (if you're sad enough) new bits
- to the program just as long as I am credited with the ORIGINAL
- version. You are not permitted to distribute the original or
- changed code for monetary gain however.
-
-
-
- ========
-
- FORENOTE
-
- --------
-
- I was playing a hand held LCD game one saturday and it was actually
- simple to play, yet quite addictive. Unusual for a hand held.
-
- Anyway, being the sad idiot that I am, I decided to convert it to
- Pascal, and give y' all a taste of the game. Hope you enjoy playing
- it, I certainly almost did ! (in between debugging)
-
-
-
- ========
-
- THE GAME
-
- --------
-
- Aliens appear on the screen, you must dig holes for them to fall in.
- If an alien falls in you must bury it in the hole, but beware! If
- an alien touches an alien in a hole it is helped out and will jump
- at the human!!!
-
- Maybe, I will write a two player version of this game. After the Bsc,
- perhaps?.
-
-
-
- Keys are (until I write a define key routine)
-
- CTRL = Dig hole
- ALT = Fill hole in (to kill an alien you do this)
-
- CURSOR UP = Move up
- CURSOR DOWN = Move down
- CURSOR LEFT = Move left
- CURSOR RIGHT = Move right
-
-
- Err... your guy is represented by a 'x' and the aliens are all 's (until
- I actually draw up some GFX! (Knowing me - NEVER!).
-
- Hell, what do you want from me, SVGA? ;^)
-
-
-
- =============
-
- FOR YOU TO DO
-
- -------------
-
- Add a title screen
- Better sound (even samples)
- Check if all aliens are dead
- 2/3/4 player mode
- A lager drinking section.... (please! I've always wanted to see a game
- with this in it!)
-
-
-
-
- =====
-
- NOTES
-
- -----
-
- NewKbdInt (The Multiple key reader) is appended to the bottom of
- this source so it can be compiled. I didn't write it - Lou Duchez
- did. Credits to him....
-
- }
-
-
-
-
- uses crt, nwkbdint; { Present in the SWAG }
-
-
-
-
- {
-
- All objects are mapped directly to the map,
- no external data types are used to contain Aliens X,Y coordinates
-
-
-
- 0 = Empty
- 1 = Wall
- 2 = Human
- 3 = Quarter Dug Hole 1
- 4 = Half Dug Hole 2
- 5 = Three Quarter Dug Hole 3
- 6 = Fully Dug Hole
-
- 20..40 = Alien (In various stages of falling.. 40 = Not inhole)
- }
-
-
-
-
- const Empty = 0;
- Wall = 1;
- Human = 2;
- QuarterDugHole = 3;
- HalfDugHole = 4;
- ThreeQuarterDugHole = 5;
- FullyDugHole = 6;
-
- AlienFilledIn = 19;
- AlienCompletelyBuried = 30;
- AlienBeginsClimbOut = 36;
- AlienAlmostBuried = 40;
- AlienHalfBuried = 50;
- NormalAlien = 70;
- AlienTripped = NormalAlien-5;
-
- Amateur = 1;
- Pro = 2;
- Kamikaze = 3; { Not implemented, Pro is hard enough! }
-
- UpKey = 72;
- DownKey = 80;
- LeftKey = 75;
- RightKey = 77;
- DigKey = 29;
- FillKey = 56;
-
-
-
-
-
- var map : array[1..7,1..5] of byte; { Playfield }
- killedplayer : boolean;
- SkillLevel : byte;
- GameLevel : byte;
- GameSpeed : byte;
- AlienPause : byte;
-
-
- HumanX, HumanY : byte;
- Currx,Curry : byte;
-
-
-
-
-
- type AlienInfo = record
- AlienState : byte;
- AlienX, AlienY : byte;
- end;
-
-
-
-
- {
- The following values are written to the map, the values contained
- may be:
-
- 0 = Empty
- 1 = Wall
- 2 = Human
- 3 = Quarter Dug Hole 1
- 4 = Half Dug Hole 2
- 5 = Three Quarter Dug Hole 3
- 6 = Fully Dug Hole
-
- 20 + = Reserved for aliens, see constants above
-
-
- Therefore, if map[1,1] was 3 then that means a Quarter Dug hole
- is at the top left of the map.
-
- }
-
-
-
-
-
-
-
-
-
-
- procedure initmap;
- var x:byte;
- y:byte;
-
- begin
- {
- Erase all of map. If you're sad enough, like me, then you
- could design small maps, or even extend 'em to fill the
- entire screen.
- }
-
-
- for y:=1 to 5 do
- for x:=1 to 7 do
- map[x,y]:=empty;
-
- {
- Set Walls
- }
-
-
- for x:=1 to 3 do
- begin
- map[x *2,2]:=Wall;
- map[x *2,4]:=Wall;
- end;
-
- {
- Determine game speed
- }
-
- case SkillLevel of
- Amateur : GameSpeed:=6;
- Pro : GameSpeed:=2; { Life expectancy - 3 seconds }
- Kamikaze : GameSpeed:=1; { Life expectancy - NIL! }
- end;
-
- AlienPause:=GameSpeed;
-
-
- {
- Now place aliens
- }
-
-
-
- for x:=1 to 3 do
- map[x*2,1]:=NormalAlien;
-
- if gamelevel > 1 then
- begin
- map[2,3]:=NormalAlien;
- map[6,3]:=NormalAlien;
- end;
-
-
- if gamelevel > 2 then
- map[4,3]:=NormalAlien;
-
-
- {
- Place human
- }
-
- HumanX:=4;
- HumanY:=5;
-
- map[HumanX,HumanY]:=Human;
-
- end;
-
-
-
-
-
- { The following 2 procedures are NOT mine; they were written by
- Robert E. Swart and cut and pasted to this routine
-
- I modified these routines for my own use!
- }
-
-
-
- procedure Lines200;
- { Set 200 scanlines on VGA display }
- InLine(
- $B8/$01/$00/ { mov AX,$0001 }
- $CD/$10/ { int $10 }
- $B8/$00/$12/ { mov AX,$1200 }
- $B3/$30/ { mov BL,$30 }
- $CD/$10); { int $10 }
-
-
- procedure Font8x16;
- { Set 8x16 VGA-font on VGA display }
- InLine(
- $B8/$01/$00/ { mov AX,$0001 }
- $CD/$10/ { int $10 }
- $B8/$14/$11/ { mov AX,$1114 }
- $B3/$00/ { mov BL,0 }
- $CD/$10); { int $10 }
-
-
-
-
-
-
-
- procedure SetCurPos(newx, newy: byte);
- begin
- currx:=newx-1; { Conv phys to log }
- curry:=newy-1;
- end;
-
-
-
- { Faster than using the write command for only one char }
-
- procedure text(TheChar: char; TheColour: byte);
- begin
- memw[$b800: (curry * 80) + (currx SHL 1)]:=word (ord(TheChar)+(TheColour SHL 8));
- end;
-
-
-
-
-
-
-
-
- {
- ====================================================================
-
- Draw the game screen.
-
- Note: All of the aliens actually exist on map, they are not simply
- sprites overlaid on the map during draw time, so in theory you could
- fill the entire map with aliens.... Have fun!
-
- --------------------------------------------------------------------
- }
-
-
-
- procedure DrawMap;
- var x, y : byte;
-
- begin
- for y:=1 to 5 do
- for x:=1 to 7 do
- begin
- SetCurPos(x,y);
-
- case map[x,y] of
- Empty : text(' ', BLACK);
- Wall : text('#', BLUE);
- Human : text('x', RED);
- AlienCompletelyBuried..
- (AlienBeginsClimbOut-1) : text(#1, random(7) OR 1);
-
- AlienBeginsClimbout..
- (NormalAlien-1) : text(#1, GREEN);
-
- NormalAlien : text(#2, GREEN);
- QuarterDugHole : text('.',LIGHTGRAY);
-
- HalfDugHole,
- ThreeQuarterDugHole : text('o', LIGHTGRAY);
- FullyDugHole : text('O',LIGHTGRAY);
- end;
- end;
- end;
-
-
-
-
-
-
-
- {
- ==============================================================
-
- Free an alien that may be trapped at maybex, maybey on the map
-
-
- --------------------------------------------------------------
- }
-
-
-
- Procedure ReleaseAlien(maybex, maybey: byte);
- var TheObject: byte;
-
- begin
- if (maybex > 0) and (maybex < 8) and (maybey > 0) and (maybey < 6) then
- begin
- theObject:=map[maybex, maybey];
- if (theObject> AlienFilledIn) And
- (theobject < NormalAlien) Then
- map[maybex, maybey]:=NormalAlien;
- end;
- end;
-
-
-
-
-
-
-
-
-
-
- procedure MoveAliens;
- var AlienArray : Array[1..10] of AlienInfo;
- x, y, TheObject : byte;
- index : byte;
- noblank : boolean;
- NewDir,
- NewXp,
- NewYp,
- ObjectHit : byte;
-
-
- begin
- dec(AlienPause);
- if AlienPause = 0 Then
-
- { Find all aliens on the map, and remember where they
- are so they can be moved later.
- }
-
-
- Begin
- AlienPause:=GameSpeed;
-
- index:=1;
- For y:=1 to 5 do
- For x:=1 to 7 do
- begin
- TheObject:=map[x,y];
- If (TheObject >=AlienCompletelyBuried) And
- (TheObject <=NormalAlien) Then
- With AlienArray[index] do
- Begin
- AlienState :=TheObject;
- AlienX :=x;
- AlienY :=y;
- Inc(index);
- End;
-
- end;
-
-
- { Now that an array of aliens has been built up,
- move em out! Also note x is being re-used. }
-
- for x:=(index-1) downto 1 do
- With AlienArray[x] do
- begin
- if AlienState = NormalAlien Then
- Begin
-
- { An alien can free it's trapped brother }
-
- releasealien(AlienX-1,AlienY);
- releasealien(AlienX+1,AlienY);
- releasealien(AlienX,AlienY-1);
- releasealien(AlienX,AlienY+1);
-
- {
- =============================
-
- Move alien in a direction
-
- -----------------------------
- }
-
-
- NewDir :=random(5)+1;
- NewXp :=AlienX;
- NewYp :=AlienY;
-
- case NewDir of
- 1: if newxp <> 1 then dec(newxp);
- 2: if newxp <> 7 then inc(newxp);
- 3: if newyp <> 1 then dec(newyp);
- 4: if newyp <> 5 then inc(newyp);
- 5..6: if newyp < humany then { A wee bit of AI :) }
- inc(newyp)
- else
- if newyp > humany then
- dec(newyp);
-
- end;
-
-
- {
- }
-
-
- noblank:=false;
- objecthit:=map[newxp,newyp];
-
- case objecthit of
- empty : map[newxp, newyp]:=NormalAlien;
- human : killedplayer:=true;
- QuarterDugHole : map[newxp, newyp]:=AlienTripped;
- HalfDugHole : map[newxp, newyp]:=AlienHalfBuried;
- ThreeQuarterDugHole : map[newxp, newyp]:=AlienAlmostBuried;
- FullyDugHole : map[newxp, newyp]:=AlienCompletelyBuried;
- else
- noblank:=true;
- end;
-
- {
- Noblank, when set FALSE means the alien has moved
- and the area where the alien was on the map shall be
- set empty.
- }
-
-
- if not noblank then
- map[AlienX, AlienY]:=Empty;
-
- { I used this for debugging. I thought it was cos
- the SWAG keyboard handler was dodgy, but it wasn't
- - my code was !!! }
-
- { gotoxy(1,24); write (chr (random(128)+32)); }
-
- end
- else
- If AlienState < NormalAlien Then
- Begin
- TheObject:=Map[AlienX, AlienY];
- Inc(TheObject,1);
- If TheObject > NormalAlien Then
- TheObject:=NormalAlien;
-
- Map[AlienX,AlienY]:=TheObject;
- End;
- end;
- end;
-
-
-
- end;
-
-
-
-
-
-
-
- {
- ======================
-
- Guess what this does ?
-
- ----------------------
- }
-
-
-
-
- Procedure DigHole(holex, holey: byte);
- var TheObject: byte;
-
- Begin
-
-
- TheObject:=Map[holex, holey];
- If TheObject = Empty Then
- Map[HoleX,Holey]:=QuarterDugHole
- Else
- If (TheObject >= QuarterDugHole)
- And (TheObject < FullyDugHole) Then
- Begin
- Sound(50);
- Delay(100);
- NoSound;
- Inc(Map[HoleX,HoleY]);
- End;
- End;
-
-
-
-
-
- {
- ==============================
-
- FILL IN A HOLE / BURY AN ALIEN
-
- ------------------------------
- }
-
-
-
-
- Procedure FillHole(holex, holey:byte);
- Var TheObject: byte;
-
- Begin
-
-
- TheObject:=Map[Holex, Holey];
- If (TheObject >= QuarterDugHole) And (TheObject <= FullyDugHole) Then
- Begin
- Sound(20);
- Delay(100);
- NoSound;
- Dec(Map[HoleX, HoleY]);
- If Map[HoleX, HoleY] < QuarterDugHole Then
- Map[HoleX, HoleY]:=Empty;
- End
- Else
- If (TheObject >=AlienFilledIn) And
- (TheObject <= AlienBeginsClimbOut) Then
- Begin
- Sound(90);
- Delay(40);
- NoSound;
- Dec(Map[HoleX,HoleY],1);
- If Map[HoleX,HoleY] <= AlienFilledIn Then
- Map[HoleX,HoleY]:=Empty;
- End;
- End;
-
-
-
-
-
-
-
-
- {
- =======================================
-
- Try and move the human to a new square.
-
- If he walks into an alien though....
-
- ---------------------------------------
- }
-
-
-
- Procedure TryMove(newx, newy: byte);
- Var TheObject: byte;
-
- Begin
- TheObject:=Map[NewX, NewY];
- If TheObject = Empty Then
- Begin
- Map[HumanX, HumanY]:=Empty;
- Map[NewX, NewY]:=Human;
- HumanX:=newx;
- HumanY:=newy;
- End
- Else
- If TheObject = NormalAlien Then
- killedplayer:=true;
- End;
-
-
-
-
-
-
-
-
-
- {
- =====================
-
- MOVE THE HUMAN AROUND
-
- ---------------------
- }
-
-
-
-
-
- Procedure MovePlayers;
-
- var currpx, currpy : byte;
- digging, burying : boolean;
-
- Begin
- currpx:=humanx;
- currpy:=humany;
-
- digging:=false;
- burying:=false;
-
- if (keydown[DigKey]) then
- digging:=true
- else
- if (keydown[FillKey]) then
- burying:=true;
-
-
- if keydown[UpKey] and (currpy <>1) then
- begin
- if digging or burying then
- begin
- if digging then
- dighole(currpx, currpy-1)
- else
- fillhole(currpx, currpy-1);
- end
- else
- trymove(currpx,currpy-1);
- end
- else
- if keydown[DownKey] and (currpy <>5) then
- begin
- if digging or burying then
- begin
- if digging then
- dighole(currpx, currpy+1)
- else
- fillhole(currpx, currpy+1);
- end
- else
- trymove(currpx,currpy+1);
- end
- else
- if keydown[LeftKey] and (currpx <>1) then
- begin
- if digging or burying then
- begin
- if digging then
- dighole(currpx-1, currpy)
- else
- fillhole(currpx-1, currpy);
- end
- else
- trymove(currpx-1,currpy);
- end
- else
- if keydown[RightKey] and (currpx <>7) then
- begin
- if digging or burying then
- begin
- if digging then
- dighole(currpx+1, currpy)
- else
- fillhole(currpx+1, currpy);
- end
- else
- trymove(currpx+1,currpy);
- end;
- end;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- begin
- randomize;
- skilllevel:=amateur;
- gamelevel:=1;
-
- initmap; { Set map up }
-
- Lines200;
- Font8x16;
-
- hookkeyboardint;
-
- repeat
- drawmap;
-
- movealiens;
- moveplayers;
- delay(125);
-
-
- until keydown[1] or killedplayer ;
- textmode(CO80);
-
- unhookkeyboardint;
- end.
-
-
-
-
- {
- If you actually play this game in it's unaltered state.. my commiserations!
- Contact address: CG93SAT@IBMRISC.DCT.AC.UK
-
- What I'd like to see more of in the SWAG are humour games... the Amiga
- has loads (cos it's a joke machine - just kidding, I own one too)
-
- Remember to write that lager drinking sim now ;) !!!
- }
-